package com.example.shirodemo.config;

import com.example.shirodemo.config.custom.CustomAuthorizingRealm;
import com.example.shirodemo.config.custom.PermissionFilter;
import com.example.shirodemo.config.thymeleaf.ShiroDialect;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.Filter;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.MapCache;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author 绫小路
 * @date 2021/1/10 16:55
 * @description
 */
@Configuration
public class ShiroConfig {

  /**
   * System.out.println(ShiroConfig.mapCache.toString()); System.out.println(ShiroConfig.mapCache.keys());
   * System.out.println(ShiroConfig.mapCache.values()); System.out.println(ShiroConfig.mapCache.size());
   */
  public static MapCache mapCache = new MapCache("123", new HashMap());

  //1 SecurityManager 流程控制
  @Bean
  public DefaultWebSecurityManager defaultWebSecurityManager(
      @Qualifier("customAuthorizingRealm") CustomAuthorizingRealm customAuthorizingRealm) {
    //开启缓存
//    customAuthorizingRealm.setCacheManager(new CustomShiroCache());//CustomShiroCache.map.get("123");
    customAuthorizingRealm.setCacheManager(new CacheManager() {
      @Override
      public <K, V> Cache<K, V> getCache(String s) throws CacheException {
        return mapCache;
      }
    });
//    customAuthorizingRealm.setCachingEnabled(true);//开启全局缓存
    customAuthorizingRealm.setAuthorizationCachingEnabled(true);

    DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
    defaultWebSecurityManager.setRealm(customAuthorizingRealm);
    return defaultWebSecurityManager;
  }

  //2 ShiroFilterFactoryBean 请求过滤器
  @Bean
  public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager) {
    ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
    shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
    //添加Shiro内置过滤器
    /**
     * Shiro内置过滤器，可以实现权限相关的拦截器
     *    常用的过滤器：
     *       anon: 无需认证（登录）可以访问
     *       authc: 必须认证才可以访问
     *       user: 如果使用rememberMe的功能可以直接访问
     *       perms： 该资源必须得到资源权限才可以访问
     *       role: 该资源必须得到角色权限才可以访问
     */
    Map<String, String> filterMap = new HashMap<String, String>();
    //授权过滤器
    //注意：当前授权拦截后，shiro会自动跳转到未授权页面
    //perms括号中的内容是权限的值
//    filterMap.put("/add", "perms[user:add]");
    filterMap.put("/admin/**", "authc");

    //swagger
    filterMap.put("/swagger-ui/**", "authc");
    filterMap.put("/v2/**", "authc");
    filterMap.put("/v3/**", "authc");

    shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);

    //登录页面
    shiroFilterFactoryBean.setLoginUrl("/login");

    //自定义过滤
    Map<String, Filter> filter = new HashMap<>();
    //添加自定义过滤器
    filter.put("authc", permissionFilter());
    shiroFilterFactoryBean.setFilters(filter);
    return shiroFilterFactoryBean;
  }

  /**
   * 注入自定义过滤器
   */
  @Bean
  public PermissionFilter permissionFilter() {
    return new PermissionFilter();
  }

  @Bean
  public ShiroDialect shiroDialect() {
    return new ShiroDialect();//添加自定义的标签
  }

}
